{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Concise Implementation of Linear Regression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The surge of deep learning has inspired the development of a variety of mature software frameworks, that\n",
    "automate much of the repetitive work of implementing deep learning models. In the previous section we\n",
    "relied only on NDarray for data storage and linear algebra and the auto-differentiation capabilities in the\n",
    "autograd package. In practice, because many of the more abstract operations, e.g. data iterators, loss\n",
    "functions, model architectures, and optimizers, are so common, deep learning libraries will give us library\n",
    "functions for these as well.\n",
    "\n",
    "We have used DataLoader to load the MNIST dataset in Section 4.5. In this section, we will learn how we can\n",
    "implement the linear regression model in Section 5.2 much more concisely with DataLoader."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Generating Data Sets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To start, we will generate the same data set as that used in the previous section."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "def synthetic_data(w, b, num_examples):\n",
    "    \"\"\"generate y = X w + b + noise\"\"\"\n",
    "    X = np.random.normal(scale=1, size=(num_examples, len(w)))\n",
    "    y = np.dot(X, w) + b\n",
    "    y += np.random.normal(scale=0.01, size=y.shape)\n",
    "    X=torch.from_numpy(X).float()\n",
    "    y=torch.from_numpy( y).float().reshape(-1,1)\n",
    "    return X,y\n",
    "true_w = torch.Tensor([2, -3.4])\n",
    "true_b = 4.2\n",
    "features, labels = synthetic_data(true_w, true_b, 1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Reading Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rather than rolling our own iterator, we can call upon DataLoader module to read data. The first step will be to instantiate an ArrayDataset, which takes in one or more NDArrays as arguments. Here, we pass in features and\n",
    "labels as arguments. Next, we will use the ArrayDataset to instantiate a DataLoader, which also requires\n",
    "that we specify a batch_size and specify a Boolean value shuffle indicating whether or not we want the\n",
    "DataLoader to shuffle the data on each epoch (pass through the dataset)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import TensorDataset,DataLoader\n",
    "def load_array(data_arrays, batch_size, is_train=True):\n",
    "    dataset=TensorDataset(*(features,labels))\n",
    "    dataloader = DataLoader(dataset=dataset,batch_size=batch_size,shuffle=True)\n",
    "    return dataloader\n",
    "batch_size =10\n",
    "data_iter = load_array((features, labels), batch_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can use data_iter in much the same way as we called the data_iter function in the previous\n",
    "section. To verify that it’s working, we can read and print the first mini-batch of instances."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0.6895, -0.9209],\n",
      "        [ 0.6262,  0.3876],\n",
      "        [ 0.7482, -0.1848],\n",
      "        [-0.0381,  2.2782],\n",
      "        [-0.7535, -0.4654],\n",
      "        [ 1.3662,  0.3763],\n",
      "        [ 0.2013,  1.0470],\n",
      "        [-0.7152,  0.8044],\n",
      "        [ 1.1146, -0.2279],\n",
      "        [ 1.3094, -0.3494]])\n",
      "tensor([[ 8.6995],\n",
      "        [ 4.1333],\n",
      "        [ 6.3130],\n",
      "        [-3.6105],\n",
      "        [ 4.2874],\n",
      "        [ 5.6487],\n",
      "        [ 1.0404],\n",
      "        [ 0.0152],\n",
      "        [ 7.2023],\n",
      "        [ 8.0014]])\n"
     ]
    }
   ],
   "source": [
    "for X, y in data_iter:\n",
    "    print(X)\n",
    "    print(y)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Define the Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When we implemented linear regression from scratch in the previous section, we had to define the model\n",
    "parameters and explicitly write out the calculation to produce output using basic linear algebra operations.\n",
    "You should know how to do this. But once your models get more complex, even qualitatively simple changes\n",
    "to the model might result in many low-level changes.\n",
    "\n",
    "We import torch.nn as nn .For standard operations, we can use nn's predefined layers, which allow us to focus especially on thelayers used to construct the model rather than having to focus on the implementation.\n",
    "To define a linear model, we first import the nn module, which defines a large number of neural network\n",
    "layers (note that “nn” is an abbreviation for neural networks). We will first define a model variable net,\n",
    "which is a Sequential instance. In nn, a Sequential instance can be regarded as a container that\n",
    "concatenates the various layers in sequence. When input data is given, each layer in the container will be\n",
    "calculated in order, and the output of one layer will be the input of the next layer. In this example, since\n",
    "our model consists of only one layer, we do not really need Sequential. But since nearly all of our future\n",
    "models will involve multiple layers, let’s get into the habit early.\n",
    "Recall the architecture of a single layer network. The layer is fully connected since it connects all inputs\n",
    "with all outputs by means of a matrix-vector multiplication. In nn, the fully-connected layer is defined\n",
    "in the Linear class. Since we only want to generate a single scalar output,we set that number to 1.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Ddf+fZdOp9d1dBQAAFgaDs0CSpht27rnnntya9M01dPTI59v8f/r+v1+JZNJbd26NbfX0tKiO++8U34/nScAAGD13n77bcf6f75ph0eVOF1+O6PnvxbWm993jjn6yfNXf4m95QZD+/70Cf3abzd5Ud6qfPATt+c+D0l64403PDskFQAA5EfgCpSwoaEhJZPJ3PrRRx9dUtg6q7q6WuPj4woGg7m9J598Uq2trY7nze18DYfDBT9mvudms1k9++yzrueePHlSO3bsWPC5e/fuVW1trSYmJvTiiy/qzJkzeuGFF3Tw4EEdPHhQH//4xwuGw3NrWSxIXui5s/s//OEP89a9VgH17NfhwoULeu211/TCCy9o69at+tjHPqa9e/dq+/btampy/xCYSCT005/+VJJ08803q76+ftH3WsrXKZFI6OWXX859D2699Vbdcsst2r17tw4ePFjwz93sx5+tZ2JiQt/85jfV29urSCSigwcPavfu3cv6swsAKA/zD8z61Vv3elTJNT/77ohe/PqXdPkX6QWfc/kXaf39g8269fMR7W07sY7Vrd71v/YRx/rNN98kcAUAoMRsunLlyhWviwCQX0NDQ+4AqlAotOKRAHM/jmmaOn/+vOP6pk2bco8X+09CvuemUikFAoGCr8v33IGBAV1//fVqbm5e8HXRaFSdnZ2L1jI5OVnwh42Fnjt3P5/FPm6h91noaxmLxVwHoOVjWZZisZiqq6tzeyMjI46v18zMTMEgc2JiQqZpSro6+/fixYuO67Ztu2YEz2cYhk6fPr3gGIvZzzkUCunIkSN5/ywMDw/nDZABAOVt7r8xJOkPnp7WluurC7xibaUnEvq7yLVfNN90m6U9X/k/df3NH9X73u9TeiKh8f/ry3rr9Wu/0D7wRFI3bs//d1wpuhCP6fmHr/07YmBgYNFfmAMAgPXFDFegRNm27fgB5o477ljxx3rggQdyj5PJpDKZzKpqK5aOjg5HeGgYhuOwL0nq6uqqqNmzDQ0NrrDVMAyFQiHXc+PxuOvrsX//fsf69OnTBd/v6aefzj2+//77HdcymYxqampcYev890yn0zJNUyMjIwXfK5PJaM+ePXmv7du3r+BrAQDlae6/VSR5Gra+966tsa4DufVNt1lq/Pqobtxep/e9/+ovJ426eh144rw+/Olrf+8O/+f9ro9VyuaHwy+9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OuGzzz7DoUOHAADbtm3DsmXLUFVVhXPnzuHee+9FXl6ew8+hsrISCQkJ+M9//oORI0dCpVKhsLAQN954I9588027iyxvvfUW3n33XWnbM2bMwJo1a7B9+3a899576Ny5M06fPg1BELBgwQJMmTLF7b8Ja+78Dr/99htWrVqF4uJiaDQa9OnTB6dOnUJlZSVOnz6N3r174+9//3uLXj87OxubNm1CcHAwbr75Znz99dc4fvw4Xn75Zeh0uhZtsyVxL1u2DB9++KH0PixZsgQvvfSStC1Pfh5Hjx7FkiVL8Ouvv+Lqq69GeXk59Ho9xo0bh5deegkjR47Et99+i1dffRX79u1r1u984sQJzJs3D3V1dRg/fjxOnz6NXbt2Yd68eYiJiWlxr+ymVFVVYdmyZThz5gyGDBmC2tpabNu2DSNGjMDrr78u+34BwOOPP476+nrpe11XV4eLFy9i/fr16N27N4CGvuYrV67ENddcg06dOqG2thYzZszAo48+CqB5/wda+n/QlaKiIsTHx0v7lz59+uDQoUM4cuQIVq5ciYsXL+L8+fOoqqrC5MmT8eKLL6JTp04Ot+Xu/1uLxYKoqCicO3cO1dXVOHfuHHJzczF27FhpW9OmTcOxY8ekx6SkpCAuLq5V78Xly5excuVKfPXVV7j11lvRrVs3bN++HSqVCikpKS2aKNRdSrzP+/btw5tvvonNmzdLF+d0Oh2uvvpqaVvLli3DsGHD8Morr+DIkSO45pprADQkcy9evIgVK1bg888/x86dO3HNNdegQ4cOuHjxIurq6vDOO++gV69e+Pe//41NmzbhmmuuQVBQEGprazFr1ixMnjxZep2tW7di9erV6Nq1K+69917pmHPu3Ll46qmnZL9fdnZ2i/apzhgMBmzevBldunRB586dcenSJXTr1q3F/++JiLxCJCIKMJ9//rkIQAQgvvfee3b3/+UvfxF///vfu9zGvn37xPfff1+85pprRADiV199ZfeYsrIysW/fvqJWqxV//fVXURRFURAEccKECSIA0WAwSPGEhISIZ86c8cBvJ7d9+3bx8ccfF1NTU8U//elP4vr168WPPvpInDVrlvi73/1O/Pbbbz36ekeOHBFvuukmceDAgeKxY8c8ss26ujrp8zpy5IjLx1ZWVopXXXWVCEAcO3asR16/UWJiohSHyWRq1nN//fVX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\n",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "SVG(filename=\"../img/singleneuron.svg\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LinearRegressionModel(torch.nn.Module): \n",
    "    def __init__(self): \n",
    "        super(LinearRegressionModel, self).__init__() \n",
    "        self.layer1 = torch.nn.Linear(2, 1,bias=True)\n",
    "    def forward(self, x): \n",
    "        y_pred = self.layer1(x)\n",
    "        return y_pred \n",
    "    \n",
    "net = LinearRegressionModel()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Initialize Model Parameters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before using net, we need to initialize the model parameters, such as the weights and biases in the linear\n",
    "regression model. we specify that each weight parameter should be randomly sampled from a normal distribution with mean 0 and standard deviation 0.01.\n",
    "The bias parameter will be initialized to zero by default. Both weight and bias will be attached with\n",
    "gradients."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "net.layer1.weight.data=torch.Tensor(np.random.normal(size=(1,2),scale=0.01,loc=0))\n",
    "net.layer1.bias.data=torch.Tensor([0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code above looks straightforward but in reality something quite strange is happening here. We are\n",
    "initializing parameters for a network even though we haven’t yet told nn how many dimensions the input\n",
    "will have. It might be 2 as in our example or it might be 2,000, so we couldn’t just preallocate enough space\n",
    "to make it work.\n",
    "nn let’s us get away with this because behind the scenes, the initialization is deferred until the first time\n",
    "that we attempt to pass data through our network. Just be careful to remember that since the parameters\n",
    "have not been initialized yet we cannot yet manipulate them in any way."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Define the Loss Function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In nn, there are many loss modules that defines various loss functions and we will directly use its implementation of squared loss (MSELoss)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "loss = torch.nn.MSELoss(reduction = \"sum\") "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define the Optimization Algorithm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Not surpisingly, we aren’t the first people to implement mini-batch stochastic gradient descent, and thus\n",
    "torch supports SGD alongside a number of variations on this algorithm through its Trainer class. When\n",
    "we instantiate the Trainer, we’ll specify the parameters to optimize over (obtainable from our net via net.parameters()), the optimization algortihm we wish to use (sgd), and a dictionary of hyper-parameters\n",
    "required by our optimization algorithm. SGD just requires that we set the value learning_rate, (here we\n",
    "set it to 0.03).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "trainer = torch.optim.SGD(net.parameters(), lr = 0.03) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Training"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You might have noticed that expressing our model through torch requires comparatively few lines of code.\n",
    "We didn’t have to individually allocate parameters, define our loss function, or implement stochastic gradient descent. Once we start working with much more complex models, the benefits of relying on torch\n",
    "abstractions will grow considerably. But once we have all the basic pieces in place, the training loop itself strikingly similar to what we did when implementing everything from scratch.\n",
    "To refresh your memory: for some number of epochs, we’ll make a complete pass over the dataset\n",
    "(train_data), grabbing one mini-batch of inputs and corresponding ground-truth labels at a time. \n",
    "\n",
    "For\n",
    "each batch, we’ll go through the following ritual:\n",
    "\n",
    "• Generate predictions by calling net(X) and calculate the loss l (the forward pass).\n",
    "\n",
    "• Calculate gradients by calling l.backward() (the backward pass).\n",
    "\n",
    "• Update the model parameters by invoking our SGD optimizer (note that trainer already knows which parameters to optimize over, so we just need to pass in the batch size.\n",
    "\n",
    "For good measure, we compute the loss after each epoch and print it to monitor progress."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 1, loss 0.10021035373210907\n",
      "epoch 2, loss 0.10903461277484894\n",
      "epoch 3, loss 0.11273252218961716\n"
     ]
    }
   ],
   "source": [
    "num_epochs = 3\n",
    "for epoch in range(num_epochs): \n",
    "    for X,y in data_iter:\n",
    "        l=loss(net(X) ,y)\n",
    "        trainer.zero_grad() \n",
    "        l.backward() \n",
    "        trainer.step() \n",
    "    l_epoch = loss(net(features), labels) \n",
    "    print('epoch {}, loss {}'.format(epoch+1, l_epoch)) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The model parameters we have learned and the actual model parameters are compared as below. We get\n",
    "the layer we need from the net and access its weight (weight) and bias (bias). The parameters we have\n",
    "learned and the actual parameters are very close."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error in estimating w tensor([-0.0026,  0.0029], grad_fn=<ThSubBackward>)\n",
      "Error in estimating b tensor(0.0023, grad_fn=<AddBackward>)\n"
     ]
    }
   ],
   "source": [
    "w = list(net.parameters())[0][0]\n",
    "print('Error in estimating w', true_w.reshape(w.shape) - w)\n",
    "b = list(net.parameters())[1][0]\n",
    "print('Error in estimating b', true_b - b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Exercises"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. If we replace l = loss(output, y) with l = loss(output, y).mean(), we need to change trainer.\n",
    "step(batch_size) to trainer.step(1) accordingly. Why?\n",
    "2. Review the pytorch documentation to see what loss functions and initialization methods are provided\n",
    "in the modules nn.loss and init. Replace the loss by Huber’s loss.\n",
    "3. How do you access the gradient of Linear.weight?\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
